<template>
  <div>
    <div style="margin-top: 45px">
      <a-row justify="center">
        <a-col :xs="{ span: 22 }" :sm="{ span: 21 }" :md="{ span: 19 }" :lg="{ span: 14 }" :xxl="{ span: 12 }">
          <div class="user">
            <div class="photo">
              <a-avatar :size="50" style="background-color: #9b59b6">{{userInfo.name[0]}}</a-avatar>
              <span>{{userInfo.rankClass}}</span>
            </div>
            <div class="data">
              <div class="item">
                <span>得分排名:</span>
                <span>{{userInfo.rank}}</span>
              </div>
              <div class="item">
                <span>正确率&#12288;:</span>
                <a-progress :percent="userInfo.acc"  strokeColor="#27ae60" style="width: 200px;"/>
              </div>
              <div class="item">
                <span>刷题进度:</span>
                <a-progress :percent="userInfo.kickProgress"  strokeColor="#27ae60" style="width: 200px;"/>
              </div>
              <div class="item">
                <span>题目总数:</span>
                <span>{{userInfo.totalQusNum}}</span>
              </div>
              <a-divider></a-divider>
              <div class="action">
                <a @click="jumpTo('/review')"><sync-outlined class="tag" />温故知新</a>
                <a @click="jumpTo('/collect')"><star-outlined class="tag" />我的收藏</a>
<!--                <a @click="jumpTo('/solve')"><edit-outlined class="tag" />做题记录</a>-->
                <a v-if="isEditorRole" @click="jumpTo('/edit')"><edit-outlined class="tag" />录入题目</a>
                <a target="_blank" href="https://www.yuque.com/docs/share/abca0c76-b615-4f46-94bd-9ed1aa7ac7df?# 《计算机刷题网站使用说明》">
                  <info-circle-outlined class="tag" />使用说明
                </a>
                <a @click="jumpTo('/message/show')" v-if="unreadMsgNum <= 0"><mail-outlined class="tag" />我的消息</a>
                <a @click="jumpTo('/message/show')" v-if="unreadMsgNum > 0"><mail-two-tone class="tag" />我的消息</a>
                <a @click="jumpTo('/message')"><comment-outlined class="tag" />联系站长</a>
<!--                <a @click="jumpTo('/message')"><comment-outlined class="tag" />赞善一下</a>-->
                <a target="_blank" href="https://www.yuque.com/docs/share/939d375d-ff01-402c-ba66-8268de45ffeb?# 《致谢名单》">
                  <heart-filled style="color: #ee5353" class="tag" />致谢列表
                </a>
                <a @click="jumpTo('/praise')"><like-outlined  class="tag" />支持站长</a>
                <a @click="jumpTo('/user/modify/1')"><setting-outlined class="tag" />修改信息</a>
              </div>
            </div>
          </div>
        </a-col>
      </a-row>
    </div>
    <a-divider>再续前缘</a-divider>
    <div>
      <a-row justify="center">
        <a-col :xs="{ span: 22 }" :sm="{ span: 21 }" :md="{ span: 19 }" :lg="{ span: 14 }" :xxl="{ span: 12 }">
          <div class="breakpoint">
            <h2 v-if="breakpoints.length === 0">你还没有做题记录!</h2>
            <div v-for="(value, index) in breakpoints" :key="index">
              <span>{{ value.subject }}:&nbsp;</span>
              <span>{{ value.category }}-第{{ value.idx + 1}}题</span>
              <span style="margin-right: 50px; float: right"><a @click="jumpToBreakpoint(value.subject)"><send-outlined />&nbsp;继续</a></span>
            </div>
          </div>
        </a-col>
      </a-row>
    </div>
    <a-divider>准备起飞</a-divider>
    <div class="job">
      <a-row justify="center">
        <a-col :xs="{ span: 22 }" :sm="{ span: 21 }" :md="{ span: 19 }" :lg="{ span: 14 }" :xxl="{ span: 12 }" >
          <a-row justify="left" :gutter="[30, 16]">
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #3498db" @click="getCateData('cs')">
                <span><code-outlined class="svg-tag" />数据结构</span><br>
                <span class="qus-num">共{{subjectQusStat.CS.num}}题&nbsp;正确率:{{subjectQusStat.CS.acc}}%</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #9b59b6" @click="getCateData('ccp')">
                <span><desktop-outlined class="svg-tag" />组成原理</span><br>
                <span class="qus-num">共{{subjectQusStat.CCP.num}}题&nbsp;正确率:{{subjectQusStat.CCP.acc}}%</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #1abc9c" @click="getCateData('os')">
                <span><windows-outlined class="svg-tag" />操作系统</span><br>
                <span class="qus-num">共{{subjectQusStat.OS.num}}题&nbsp;正确率:{{subjectQusStat.OS.acc}}%</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #e67e22" @click="getCateData('net')">
                <span><global-outlined class="svg-tag"/>计算机网络</span><br>
                <span class="qus-num">共{{subjectQusStat.NET.num}}题&nbsp;正确率:{{subjectQusStat.NET.acc}}%</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #e74c3c" @click="getCateData('fun')">
                <span><coffee-outlined class="svg-tag" />休闲刷题</span><br>
                <span class="qus-num">每次随机20题</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #f1c40f" @click="getCateData('seq')">
                <span><arrow-down-outlined class="svg-tag" />顺序刷题</span><br>
                <span class="qus-num">按年份刷题</span>
              </div>
            </a-col>
            <a-col :xs="12" :md="8">
              <div class="menu" style="background-color: #34495e" @click="getCateData('udf')">
                <span><dashboard-outlined class="svg-tag" />自主组题</span><br>
                <span class="qus-num">自定义刷题</span>
              </div>
            </a-col>
          </a-row>
        </a-col>
      </a-row>
    </div>
    <a-divider>排行榜</a-divider>
    <div class="rank">
      <a-row justify="center">
        <a-col :xs="{ span: 22 }" :sm="{ span: 21 }" :md="{ span: 19 }" :lg="{ span: 14 }" :xxl="{ span: 12 }">
          <div>
            <fire-filled style="color: #e74c3c"/>&nbsp;段位&nbsp;
            <check-circle-filled style="color: #2ecc71"/>&nbsp;综合得分&nbsp;
            <bulb-filled style="color: #f1c40f"/>&nbsp;已刷题数
          </div>
          <a-list item-layout="horizontal" :data-source="rankList">
            <template #renderItem="{ item }">
              <a-list-item>
                <a-list-item-meta>
                  <template #title>
                    <span class="rank-item">{{ item.name }}</span>
                    <span class="rank-item-info"><fire-filled style="color: #e74c3c"/>&nbsp;{{item.rankClass}}&nbsp;</span>
                    <span class="rank-item-info"><check-circle-filled style="color: #2ecc71"/>&nbsp;{{item.acc}}&nbsp;分</span>
                    <span class="rank-item-info"><bulb-filled style="color: #f1c40f"/>&nbsp;{{item.kickNumber}}</span>
                  </template>
                  <template #avatar>
                    <a-avatar style="background-color: #1abc9c">{{ item.rank }}</a-avatar>
                  </template>
                </a-list-item-meta>
              </a-list-item>
            </template>
          </a-list>
        </a-col>
      </a-row>
    </div>
    <div class="footer">
      <span style="font-family:arial,serif;">Copyright &copy; 2022 Just for fun.</span>
    </div>
  </div>
</template>

<script lang="ts">
import { Avatar, Col, Divider, List, message, Progress, Row } from 'ant-design-vue'
import {
  ArrowDownOutlined,
  BulbFilled,
  CheckCircleFilled,
  CodeOutlined,
  CoffeeOutlined,
  CommentOutlined,
  DashboardOutlined,
  DesktopOutlined,
  EditOutlined,
  FireFilled,
  GlobalOutlined,
  HeartFilled,
  InfoCircleOutlined,
  LikeOutlined,
  MailOutlined,
  MailTwoTone,
  SendOutlined,
  SettingOutlined,
  StarOutlined,
  SyncOutlined,
  WindowsOutlined
} from '@ant-design/icons-vue'
import { onMounted, reactive, ref } from 'vue'
import { getBreakpoint, getMsgNumUnread, getUserRanking, getUserStatistic } from '@/service'
import { checkToken, isEditor, subjectCode2Name, subjectName2Code } from '@/utils/check'
import { useRouter } from 'vue-router'
import {
  BREAKPOINT_KEY,
  SUBJECT_STAT_KEY,
  UNREAD_MSG_NUM,
  USER_INFO_KEY,
  USER_RANK_KEY
} from '@/utils/constants'
import { Breakpoint } from '@/utils/ds'
import {
  getCache, setCache,
  getCacheLong, checkUserUpdateExpire, getUserName,
  setCacheLongWithTime
} from '@/utils/common'

interface RankItem {
  name: string,
  rank: number,
  rankClass: string,
  acc: string,
  kickNumber: number
}

interface UserInfo {
  name: string,
  acc: number,
  rank: number,
  kickNumber: number,
  rankClass: string,
  kickProgress: number,
  totalQusNum: number
}

interface SubjectQusItem {
  num: number,
  acc: number
}

interface SubjectQusStat {
  CS: SubjectQusItem,
  OS: SubjectQusItem,
  CCP: SubjectQusItem,
  NET: SubjectQusItem
}

export default {
  name: 'WorkGround',
  components: {
    ARow: Row,
    ACol: Col,
    AAvatar: Avatar,
    AProgress: Progress,
    ADivider: Divider,
    InfoCircleOutlined,
    HeartFilled,
    WindowsOutlined,
    GlobalOutlined,
    CodeOutlined,
    DesktopOutlined,
    ArrowDownOutlined,
    DashboardOutlined,
    CoffeeOutlined,
    EditOutlined,
    StarOutlined,
    SendOutlined,
    BulbFilled,
    CheckCircleFilled,
    FireFilled,
    CommentOutlined,
    MailOutlined,
    MailTwoTone,
    SettingOutlined,
    SyncOutlined,
    LikeOutlined,
    AList: List,
    AListItem: List.Item,
    AListItemMeta: List.Item.Meta
  },
  setup () {
    const unreadMsgNum = ref<number>(0)
    const userAvatarColor = ref(['#87d068', '#953bdb', '#1890ff', '#f56a00'])
    const itemLayout1 = reactive({
      xs: { span: 10 },
      sm: { span: 10 },
      md: { span: 9 },
      lg: { span: 5 }
    })
    const itemLayout2 = reactive({
      xs: { span: 10, offset: 1 },
      sm: { span: 10, offset: 1 },
      md: { span: 9, offset: 1 },
      lg: { span: 5, offset: 1 }
    })
    const rankList = ref<RankItem[]>([])
    const router = useRouter()
    const userInfo = ref<UserInfo>({
      name: '计算机',
      acc: 0,
      rank: 1,
      kickNumber: 0,
      rankClass: '塑料',
      kickProgress: 0,
      totalQusNum: 170
    })
    const subjectQusStat = ref<SubjectQusStat>({
      CS: { num: 0, acc: 100 },
      OS: { num: 0, acc: 100 },
      CCP: { num: 0, acc: 100 },
      NET: { num: 0, acc: 100 }
    })
    const isEditorRole = ref(false)
    const breakpoints = ref<Breakpoint[]>([])

    const cacheUserRanking = () => {
      const cache = getCacheLong(USER_RANK_KEY)
      if (cache.length > 0) {
        const d = JSON.parse(cache)
        if (!checkUserUpdateExpire(d.time)) {
          return false
        }
        rankList.value = d.data
        return true
      }
      return false
    }

    const setUserRanking = () => {
      if (cacheUserRanking()) {
        return
      }

      getUserRanking()
        .then((response) => {
          if (response.status === 200) {
            const resp = response.data
            if (resp.code !== 0) {
              return
            }

            const ranking = resp.data
            if (ranking !== null) {
              ranking.forEach((e:string, idx: number) => {
                // 叶勇,王者,93,41
                const f:string[] = e.split(',')
                const n:string = f[0].substring(0, 3)
                rankList.value.push({
                  name: n,
                  rank: idx + 1,
                  rankClass: f[1],
                  acc: f[2],
                  kickNumber: parseInt(f[3])
                })
              })
              setCacheLongWithTime(USER_RANK_KEY, rankList.value)
            }
          }
        })
        .catch((err) => {
          console.log(err)
        })
    }

    const cacheUserInfo = (): boolean => {
      const cache = getCacheLong(USER_INFO_KEY)
      if (cache.length === 0) {
        return false
      }
      const d = JSON.parse(cache)
      if (!checkUserUpdateExpire(d.time)) {
        return false
      }
      userInfo.value = d.data
      return true
    }

    const cacheSubjectQusStat = (): boolean => {
      const cache = getCacheLong(SUBJECT_STAT_KEY)
      if (cache.length === 0) {
        return false
      }
      const d = JSON.parse(cache)
      if (!checkUserUpdateExpire(d.time)) {
        return false
      }
      subjectQusStat.value = d.data
      return true
    }

    const setUserInfo = () => {
      if (cacheUserInfo() && cacheSubjectQusStat()) {
        return
      }
      const token = checkToken()
      if (token.length === 0) {
        message.info('身份失效，请先登录')
        return
      }
      // 获取用户数据信息
      getUserStatistic(token)
        .then((response) => {
          if (response.status !== 200) {
            return
          }
          const resp = response.data
          // console.log(resp)
          if (resp.code !== 0) {
            return
          }
          const data = resp.data
          if (data !== null) {
            const total = data.total
            const pure = data.pure
            const correct = data.correct
            const rank = data.rank
            const rankClass = data.rankClass
            const qusTotal = data.qusTotal

            const u = userInfo.value
            if (total === 0) {
              u.acc = 0
            } else {
              u.acc = Math.round((correct / total) * 100)
            }
            if (qusTotal === 0) {
              u.kickProgress = 0
            } else {
              u.kickProgress = Math.round((pure / qusTotal) * 100)
            }
            u.kickNumber = pure
            u.rank = rank
            u.rankClass = rankClass
            u.totalQusNum = qusTotal
            u.name = getUserName()

            setCacheLongWithTime(USER_INFO_KEY, u)

            const subInfo = subjectQusStat.value
            let e = parseSubjectStat(data.CS as string)
            subInfo.CS.num = e[0]
            subInfo.CS.acc = Math.round((e[1] / (e[1] + e[2])) * 100)

            e = parseSubjectStat(data.OS as string)
            subInfo.OS.num = e[0]
            subInfo.OS.acc = Math.round((e[1] / (e[1] + e[2])) * 100)

            e = parseSubjectStat(data.CCP as string)
            subInfo.CCP.num = e[0]
            subInfo.CCP.acc = Math.round((e[1] / (e[1] + e[2])) * 100)

            e = parseSubjectStat(data.NET as string)
            subInfo.NET.num = e[0]
            subInfo.NET.acc = Math.round((e[1] / (e[1] + e[2])) * 100)
            setCacheLongWithTime(SUBJECT_STAT_KEY, subInfo)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    }

    const parseSubjectStat = (value: string) => {
      // 0 题目个数 1 正确率
      const s = value.split(',')
      const arr:number[] = []
      arr.push(parseInt(s[0]))
      arr.push(parseInt(s[1]))
      arr.push(parseInt(s[2]))
      return arr
    }

    const getBreakpointOnLoad = () => {
      const bks = sessionStorage.getItem(BREAKPOINT_KEY)
      if (bks !== null) {
        const breakpoint = JSON.parse(bks)
        breakpoints.value.length = 0
        breakpoint.forEach((bk:any) => {
          const b: Breakpoint = {
            id: bk.id,
            pid: bk.pid,
            idx: bk.idx,
            subject: bk.subject,
            category: bk.category
          }
          b.subject = subjectCode2Name(b.subject)
          breakpoints.value.push(b)
        })
        return
      }
      getBreakpoint()
        .then((response) => {
          if (response.status !== 200) {
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            return
          }
          sessionStorage.setItem(BREAKPOINT_KEY, JSON.stringify(resp.data))
          breakpoints.value.length = 0
          resp.data.forEach((bk:Breakpoint) => {
            const b: Breakpoint = {
              pid: bk.pid,
              idx: bk.idx,
              subject: bk.subject,
              category: bk.category
            }
            b.subject = subjectCode2Name(b.subject)
            breakpoints.value.push(b)
          })
        })
    }

    const getMsgInfo = () => {
      const d = getCache(UNREAD_MSG_NUM)
      if (d.length > 0) {
        unreadMsgNum.value = JSON.parse(d)
        return
      }

      getMsgNumUnread()
        .then(response => {
          if (response.status !== 200) {
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.warn('获取消息列表失败')
            return
          }
          unreadMsgNum.value = resp.data
          setCache(UNREAD_MSG_NUM, JSON.stringify(resp.data))
        })
    }
    onMounted(() => {
      // console.log(localStorage.getItem(tokenName))
      setUserInfo()
      // 设置用户排名
      setUserRanking()
      getBreakpointOnLoad()
      getMsgInfo()
      isEditorRole.value = isEditor()
    })

    const getCateData = (cate: string) => {
      router.push({
        path: `/solve/${cate}`
      })
    }

    const jumpTo = (url: string) => {
      router.push({
        path: url
      })
    }

    const jumpToBreakpoint = (name: string) => {
      const code = subjectName2Code(name)
      router.push({
        path: `/solve/bk_${code}`
      })
    }

    return {
      userAvatarColor,
      itemLayout1,
      itemLayout2,
      rankList,
      userInfo,
      subjectQusStat,
      isEditorRole,
      breakpoints,
      unreadMsgNum,
      getCateData,
      jumpTo,
      jumpToBreakpoint
    }
  }
}
</script>

<style scoped>
.user {
  margin-top: 10px;
  padding: 5px;
  border-radius: 20px;
  /*box-shadow:-2px 1px 3px rgba(0, 0, 0, 0.5);*/
  box-shadow: rgba(0, 0, 0, 0.25) 0 3px 8px;
  /*background-color: #f7f7fc;*/
}

.user .photo span:last-child{
  font-size: 0.8em;
  vertical-align: bottom;
  margin-left: 8px;
  letter-spacing: 3px;
}

.user .data {
  padding-left: 10px;
  margin-top: 10px;
}

.user .data .item {
  margin-top: 6px;
}

.user .data .action {
  margin-top: 10px;
  user-select: none;
}

.user .data .action a{
  display: inline-block;
  letter-spacing: 1px;
  font-size: 1.2em;
  text-decoration: none;
  color: #000000;
  margin-left: 15px;
}

/*.user .data .action a:not(:first-child){*/
/*  margin-left: 30px;*/
/*}*/

.user .data .item span:nth-child(1){
  font-size: 1.1em;
  letter-spacing: 5px;
  width: 100px;
  display: inline-block;
}

.job {
  margin-top: 20px;
}

.job .menu {
  /*height: 80px;*/
  border-radius: 10px;
  padding: 5px;
  text-align: center;
  box-shadow: 1px 2px 2px #aaaaaa;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
}

/*.job .menu:hover {*/
/*  box-shadow: 2px 4px 4px #2c2c2d;*/
/*  transform: scale(1.1);*/
/*}*/

.job .menu span {
  color: white;
  font-size: 1.5em;
  display: inline-block;
  letter-spacing: 2px;
}

.job .menu .qus-num {
  display: inline-block;
  font-size: 1em;
  letter-spacing: 0;
}

.job .menu .svg-tag {
  font-size: 1.1em;
  margin-right: 5px;
}
.rank-item {
  font-weight: bold;
  font-size: 1.2em;
  display: inline-block;
  width: 60px;
}

.rank-item-info {
  font-size: 1.1em;
  display: inline-block;
  margin-left: 4px;
  width: 80px;
}

@media screen and (max-width: 450px) and (min-width: 375px){
  .rank-item {
    font-weight: bold;
    font-size: 1em;
    display: inline-block;
    width: 45px;
  }

  .rank-item-info {
    font-size: 0.9em;
    display: inline-block;
    width: 60px;
  }
}

@media screen and (max-width: 376px){
  .rank-item {
    font-weight: bold;
    font-size: 0.8em;
    display: inline-block;
    width: 42px;
  }

  .rank-item-info {
    font-size: 0.7em;
    display: inline-block;
    width: 50px;
  }
}

.footer {
  text-align: center;
  margin-top: 10px;
  margin-bottom: 5px;
  padding: 5px;
}
.footer span {
  display: inline-block;
  font-weight: 400;
}

.action a {
  margin-bottom: 5px;
}

.action .tag {
  margin-right: 2px;
}

.breakpoint {
  font-size: 1.2em;
}

.breakpoint span {
  letter-spacing: 1px;
}

</style>
